package com.wb.business.config;

import com.ruoyi.project.relation.domain.ao.SyncActionRequest;
import com.ruoyi.project.relation.domain.ao.SyncActonResponse;
import com.wb.business.service.BusinessEntityService;
import org.apache.commons.lang3.StringUtils;
import org.shoukaiseki.common.exception.MessageVirtualException;
import org.shoukaiseki.common.utils.SpringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * com.wb.business.config.BusinessEntityManager
 * <br>
 *
 * @author shoukaiseki ブログ http://www.shoukaiseki.top/<br> E-メール jiang28555@Gmail.com<br>
 * @date 2021-06-23 21:57:30<br>
 */
@Configuration
public class BusinessEntityManager implements ApplicationContextAware
{


    private static final Logger logger=LoggerFactory.getLogger(BusinessEntityManager.class);

//    不能采用注入形式,不然没有实现类会报错
//    @Autowired
//    private List<BusinessEntityService> businessEntityServiceList;

    private Map<String, Object> businessEntityServiceMap=new ConcurrentHashMap<>();

    private static Map<String, ConcurrentHashMap<String, CopyOnWriteArrayList<Method>>> syncActionBeanMap=new ConcurrentHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, BusinessEntityService> beans = applicationContext.getBeansOfType(BusinessEntityService.class);
        for (BusinessEntityService businessEntityService : beans.values()) {
            businessEntityService.setBusinessEntityManager(this);
//            businessEntityService.setBusinessEntityManager(this);
            String tableName = businessEntityService.getTableName();
            logger.info("businessEntityService={},tableName={}",businessEntityService,tableName);
            if (tableName==null) {
                logger.error("tableName为空,{}",businessEntityService);
                //有时候为空的,不用管,只为了注入 BusinessEntityManager
                continue;
            }
            Object businessEntityServiceImpl = businessEntityService.getBusinessEntityServiceImpl();
            if (businessEntityServiceImpl==null) {
                logger.error("businessEntityServiceImpl为空,{}",businessEntityService);
            }

            businessEntityServiceMap.put(tableName,businessEntityServiceImpl);


            Object impl=businessEntityServiceImpl;
            Class<?> implClazz = impl.getClass();
            if (AopUtils.isAopProxy(businessEntityServiceImpl)) {
                implClazz=AopUtils.getTargetClass(businessEntityServiceImpl);
            }

//            businessEntityServiceMap.put(tableName,implClazz);

            Method[] allDeclaredMethods = ReflectionUtils.getAllDeclaredMethods(implClazz);
            ConcurrentHashMap<String, CopyOnWriteArrayList<Method>> methodMap = new ConcurrentHashMap<>();
            syncActionBeanMap.put(tableName, methodMap);
            for (Method method : allDeclaredMethods) {
                String name = method.getName();
                CopyOnWriteArrayList<Method> methodList = new CopyOnWriteArrayList<>();
                methodMap.put(name, methodList);
                Class<?>[] parameterTypes = method.getParameterTypes();
                if (parameterTypes.length==1) {
                    methodList.add(method);
                }
            }
        }
    }


//    @PostConstruct
//    void init(){
//        businessEntityServiceMap=new HashMap<>();
//        if(businessEntityServiceList==null){
//            return;
//        }
//        for (BusinessEntityService businessEntityService : businessEntityServiceList) {
//            String tableName = businessEntityService.getTableName();
//            logger.info("businessEntityService={},tableName={}",businessEntityService,tableName);
//            if (tableName==null) {
//                logger.error("tableName为空,{}",businessEntityService);
//            }
//            Object businessEntityServiceImpl = businessEntityService.getBusinessEntityServiceImpl();
//            if (businessEntityServiceImpl==null) {
//                logger.error("businessEntityServiceImpl为空,{}",businessEntityService);
//            }
//
//            businessEntityServiceMap.put(tableName,businessEntityServiceImpl);
//        }
//
//    }

    public BusinessEntityService getBusinessEntityService(String ownerName){
        if(StringUtils.isEmpty(ownerName)){
            throw new RuntimeException("ownerName 为空");
        }
//        Object bean = SpringUtils.getBean(businessEntityServiceMap.get(ownerName));
        Object bean =businessEntityServiceMap.get(ownerName);
        return (BusinessEntityService)bean;
    }


    public <T> T getServiceImpl(String ownerName){
//        Object bean = SpringUtils.getBean(businessEntityServiceMap.get(ownerName));
        Object bean =businessEntityServiceMap.get(ownerName);
        return (T)bean;
    }

    /**
     * 获取 beanName 对应的方法,参数个数只能为1个,而且同名参数可能会无效
     * @param ownerName
     * @param beanName
     * @return
     */
    public static Method getMethod(String ownerName,String beanName){
        ConcurrentHashMap<String, CopyOnWriteArrayList<Method>> methodMap = syncActionBeanMap.get(ownerName);
        List<Method> methodList = methodMap.get(beanName);
        if(methodList==null||methodList.size()==0){
            throw new RuntimeException(ownerName+"["+beanName+"]不存在该方法,或者该方法参数超过1个(不知该如何调用)");
        }
        if(methodList.size()>1){
            throw new RuntimeException(ownerName+"["+beanName+"]存在多个方法,无法判定调用哪个方法");
        }
        return methodList.get(0);
    }


    /**
     * 获取appName的标题名称,中文
     * @param ownerName
     * @param appName
     * @return
     */
    public String getAppNameTitle(String ownerName,String appName){
        Object o = businessEntityServiceMap.get(ownerName);
        if(o==null){
            return "";
        }
        return getBusinessEntityService(ownerName)!=null?getBusinessEntityService(ownerName).getTitle(appName):"";
    }

    /**
     * 获取请求预留的 bom 业务名称
     * @param ownerName
     * @param ownerId
     * @param bomId
     * @param String
     * @return
     */
    public String getRequestReserveBomBusinessName(String ownerName,Long ownerId,Long bomId){
        BusinessEntityService businessEntityService = getBusinessEntityService(ownerName);
        if (businessEntityService ==null) {
           throw new MessageVirtualException("业务 service 不存在 {}").format(ownerName);
        }
        String reserveBomBusinessName = businessEntityService.getRequestReserveBomBusinessName(ownerName, ownerId, bomId);
        if (StringUtils.isEmpty(reserveBomBusinessName)) {
            throw new MessageVirtualException("业务 service 获取请求预留bom业务名称失败 {}").format(ownerName);
        }
        return reserveBomBusinessName;
    }

    /**
     * 获取响应预留的 bom 业务名称
     * @param ownerName
     * @param ownerId
     * @param bomId
     * @param String
     * @return
     */
    public String getResponseReserveBomBusinessName(String ownerName,Long ownerId,Long bomId){
        BusinessEntityService businessEntityService = getBusinessEntityService(ownerName);
        if (businessEntityService ==null) {
            throw new MessageVirtualException("业务 service 不存在 {}").format(ownerName);
        }
        String reserveBomBusinessName = businessEntityService.getResponseReserveBomBusinessName(ownerName, ownerId, bomId);
        if (StringUtils.isEmpty(reserveBomBusinessName)) {
            throw new MessageVirtualException("业务 service 获取响应预留bom业务类型失败 {}").format(ownerName);
        }
        return reserveBomBusinessName;
    }


    /**
     * 获取请求预留的 bom 业务类型
     * @param ownerName
     * @param ownerId
     * @param bomId
     * @param String
     * @return
     */
    public String getRequestReserveBomOwnerType(String ownerName,Long ownerId,Long bomId){
        BusinessEntityService businessEntityService = getBusinessEntityService(ownerName);
        if (businessEntityService ==null) {
            throw new MessageVirtualException("业务 service 不存在 {}").format(ownerName);
        }
        String reserveBomBusinessName = businessEntityService.getRequestReserveBomOwnerType(ownerName, ownerId, bomId);
        if (StringUtils.isEmpty(reserveBomBusinessName)) {
            throw new MessageVirtualException("业务 service 获取请求预留bom业务类型失败 {}").format(ownerName);
        }
        return reserveBomBusinessName;
    }

    /**
     * 获取请求预留的 bom 业务类型
     * @param ownerName
     * @param ownerId
     * @param bomId
     * @param String
     * @return
     */
    public String getBusinessType(String ownerName,Long ownerId){
        BusinessEntityService businessEntityService = getBusinessEntityService(ownerName);
        if (businessEntityService ==null) {
            throw new MessageVirtualException("业务 service 不存在 {}").format(ownerName);
        }
        String orderType = businessEntityService.getBusinessType(ownerId);
        if (StringUtils.isEmpty(orderType)) {
            throw new MessageVirtualException("业务 service 获取 业务类型失败 {}").format(ownerName);
        }
        return orderType;
    }

    /**
     * 获取响应预留的 bom 业务类型
     * @param ownerName
     * @param ownerId
     * @param bomId
     * @param String
     * @return
     */
    public String getResponseReserveBomOwnerType(String ownerName,Long ownerId,Long bomId){
        BusinessEntityService businessEntityService = getBusinessEntityService(ownerName);
        if (businessEntityService ==null) {
            throw new MessageVirtualException("业务 service 不存在 {}").format(ownerName);
        }
        String reserveBomBusinessName = businessEntityService.getResponseReserveBomOwnerType(ownerName, ownerId, bomId);
        if (StringUtils.isEmpty(reserveBomBusinessName)) {
            throw new MessageVirtualException("业务 service 获取响应预留bom业务名称失败 {}").format(ownerName);
        }
        return reserveBomBusinessName;
    }

    @Transactional
    public Map<String,SyncActonResponse> syncAction(List<SyncActionRequest> syncActionRequestList){
        return SpringUtils.getAopProxy(this).baseSyncActionList(syncActionRequestList);
    }

    @Transactional
    public Map<String,SyncActonResponse> baseSyncActionList(List<SyncActionRequest> syncActionRequestList){
        Map<String,SyncActonResponse> map = new HashMap<>();
        for (SyncActionRequest syncActionRequest : syncActionRequestList) {
            SyncActonResponse syncActonResponse = syncAction(syncActionRequest);
            map.put(syncActionRequest.getAliasName(),syncActonResponse);
        }
        return map;
    }


    /**
     * 同步触发
     * @param syncActionRequest
     * @return
     */
    @Transactional
    public SyncActonResponse syncAction(SyncActionRequest syncActionRequest){
        BusinessEntityService businessEntityService = getBusinessEntityService(syncActionRequest.getOwnerName());
        return businessEntityService.syncAction(syncActionRequest);
    }


}
